﻿@page "/diagram/connectors"

@using Syncfusion.Blazor.Diagrams
@using System.Collections.ObjectModel
@using Syncfusion.Blazor.Buttons
@using DiagramShapes = Syncfusion.Blazor.Diagrams.Shapes

@inherits SampleBaseComponent;

<SampleDescription>
  <p>  This sample visualizes the data flow in a marketing process using predefined shapes and connectors. Different types of connectors and decorators are used to customize the appearance, path, and direction of the data flow.</p>  
    <p style="font-weight: bold;">A new blazor diagram component which provides better performance than the existing diagram control in Blazor WebAssembly App. It is available in preview mode. Check the samples <a target='_blank' href='diagramcomponent/flowchart'>here</a>.</p>
</SampleDescription>
<ActionDescription>
   <p>In this example, you can see how to add connectors to connect shapes and how to customize the appearance of the connectors. You can use the style property of the connector to customize its stroke style. You can use the <a target='_blank' href='https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Diagrams.DiagramConnector.html#Syncfusion_Blazor_Diagrams_DiagramConnector_CornerRadius'>CornerRadius</a> property to add connectors with rounded corners.</p>
   <p>To change the appearance, click different styles in the property panel. Additionally, you can see how to lock the connectors to disable editing. The <a target='_blank' href='https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Diagrams.DiagramConnector.html#Syncfusion_Blazor_Diagrams_DiagramConnector_Constraints'>Constraints</a> property of a connector enables or disables editing. In this example, the shapes are automatically arranged using a hierarchical tree layout.</p>
   <p>To change the position of the descriptions, select a node and choose the template in the property panel.</p><br>
</ActionDescription>

<div class="col-lg-9 control-section" style="background: white;border-right: 1px solid #D7D7D7;">
    <div id="diagram-space" class="content-wrapper" style="width:100%;background: white;">
        <SfDiagram @ref="@Diagram" Height="580px"
                    Nodes="@NodeCollection"
                    NodeDefaults="@NodeDefaults"
                    Connectors="@ConnectorCollection"
                    ConnectorDefaults="@ConnectorDefaults"
                   SelectedItems="@SelectedItems">
            <DiagramEvents SelectionChanged="@SelectionChange"></DiagramEvents>
            <DiagramSnapSettings Constraints="@SnapConstraints.None"></DiagramSnapSettings>
            <DiagramPageSettings>
                <DiagramFitOptions CanFit="true" Mode="FitModes.Width"></DiagramFitOptions>
            </DiagramPageSettings>

        </SfDiagram>
    </div>
</div>
@*Hidden:Lines*@
<div class="col-lg-3 property-section">
    <style>
        .image-pattern-style {
            background-color: white;
            background-size: contain;
            background-repeat: no-repeat;
            height: 45px;
            width: calc((100% - 13px) / 3);
            cursor: pointer;
            border: 1px solid #D5D5D5;
            background-position: center;
            float: left;
        }

            .image-pattern-style:hover {
                border-color: gray;
                border-width: 2px;
            }

        .row {
            margin-left: 0px;
            margin-right: 0px;
        }

        .sb-child-row {
            padding-top: 8px;
        }

        .row-header {
            font-size: 13px;
            font-weight: 600;
        }

        .e-radio + label .e-label {
            display: inline-block;
            font-family: "Helvetica Neue", "Helvetica", "Arial", sans-serif, "-apple-system", "BlinkMacSystemFont";
            font-size: 12px;
            font-weight: normal;
            line-height: 1;
            padding-left: 24px;
            vertical-align: text-top;
            white-space: normal;
            color: #212529;
        }

        .e-selected-style {
            border-color: #006CE6;
            border-width: 2px;
        }

        .e-checkbox-wrapper .e-label {
            font-size: 12px;
        }
    </style>

    <div class="property-panel-header">
        Properties
    </div>
    <div class="row row-header">
        Apply To
    </div>
    <div class="row" style="padding-top: 8px">
        <SfRadioButton Label="All Connectors" Name="NodeSelection" Value=@Value1 @bind-Checked="@CheckValue" TChecked="string"></SfRadioButton>

    </div>
    <div class="row" style="padding-top: 8px">
        <SfRadioButton Label="Selected Connector" Name="NodeSelection" Value=@Value2 @bind-Checked="@CheckValue" TChecked="string"></SfRadioButton>
    </div>
    <div class="row row-header" style="padding-top: 10px;">Appearance</div>
    <div class="row" style="padding-top: 8px">
        <div class="@CssClass["Straight"]" @onclick="@(() => ChangeConnectorAppearance("Straight"))" style="background-image: url(images/diagram/connector/straight.png); margin-right: 3px">
        </div>
        <div class="@CssClass["Orthogonal"]" @onclick="@(() => ChangeConnectorAppearance("Orthogonal"))" style="background-image: url(images/diagram/connector/orthogonal.png); margin: 0px 3px">
        </div>
        <div class="@CssClass["Bezier"]" @onclick="@(() => ChangeConnectorAppearance("Bezier"))" style="background-image: url(images/diagram/connector/bezier.png); margin-left: 3px">
        </div>
    </div>
    <div class="row" style="padding-top: 8px">
        <div class="@CssClass["StraightWithStroke"]" @onclick="@(() => ChangeConnectorAppearance("StraightWithStroke"))" style="background-image: url(images/diagram/connector/straight-with-stroke.png); margin-right: 3px">
        </div>
        <div class="@CssClass["OrthogonalWithStroke"]" @onclick="@(() => ChangeConnectorAppearance("OrthogonalWithStroke"))" style="background-image: url(images/diagram/connector/orthogonal-with-stroke.png); margin: 0px 3px">
        </div>
        <div class="@CssClass["BezierWithStroke"]" @onclick="@(() => ChangeConnectorAppearance("BezierWithStroke"))" style="background-image: url(images/diagram/connector/bezier-with-stroke.png); margin-left: 3px">
        </div>
    </div>
    <div class="row" style="padding-top: 8px">
        <div class="@CssClass["StraightWithDashArray"]" @onclick="@(() => ChangeConnectorAppearance("StraightWithDashArray"))" style="background-image: url(images/diagram/connector/straight-with-dash-array.png); margin-right: 3px">
        </div>
        <div class="@CssClass["OrthogonalWithDashArray"]" @onclick="@(() => ChangeConnectorAppearance("OrthogonalWithDashArray"))" style="background-image: url(images/diagram/connector/orthogonal-with-dash-array.png); margin: 0px 3px">
        </div>
        <div class="@CssClass["BezierWithDashArray"]" @onclick="@(() => ChangeConnectorAppearance("BezierWithDashArray"))" style="        background-image: url(images/diagram/connector/bezier-with-dash-array.png); margin-left: 3px">
        </div>
    </div>
    <div class="row" style="padding-top: 8px">
        <div class="@CssClass["CornerRadious"]" @onclick="@(() => ChangeConnectorAppearance("CornerRadious"))" style="background-image: url(images/diagram/connector/corner-radius.png); margin-right: 3px">
        </div>
        <div class="@CssClass["SourceDecorator"]" @onclick="@(() => ChangeConnectorAppearance("SourceDecorator"))" style="background-image: url(images/diagram/connector/source-decorator.png); margin: 0px 3px">
        </div>
        <div class="@CssClass["SourceDecoratorWithDashArray"]" @onclick="@(() => ChangeConnectorAppearance("SourceDecoratorWithDashArray"))" style="background-image: url(images/diagram/connector/source-decorator-with-dash-array.png); margin-left: 3px">
        </div>
    </div>
    <div class="row property-panel-content" style="padding-top: 10px">
        <div class="row row-header">
            Behavior
        </div>
        <div class="row" style="padding-top: 8px">
            <SfCheckBox @ref="@Checkboxcontrol" ID="chkLock" Label="Lock" Checked="@checkboxvalue" ValueChange="@ConstraintsChange" TChecked="bool"/>
        </div>
    </div>
</div>
@*End:Hidden*@


@code
{
    private string CheckValue = "All shapes";
    SfCheckBox<bool> Checkboxcontrol;

    private string Value1 = "All shapes";
    private string Value2 = "Selected Shapes";
    bool checkboxvalue = false;
    const string defaultCssClass = "image-pattern-style";

    const string selectedCssClass = "image-pattern-style e-selected-style";
    int connectorCount;
    string selectedType = "Bezier";

    // Reference to diagram
    SfDiagram Diagram;

    public Dictionary<string, string> CssClass { get; set; }

    // Defines diagram's nodes collection
    public ObservableCollection<DiagramNode> NodeCollection { get; set; }

    // Defines diagram's connector collection
    public ObservableCollection<DiagramConnector> ConnectorCollection { get; set; }

    // Defines default values for DiagramNode object
    public DiagramNode NodeDefaults { get; set; }

    // Defines default values for DiagramConnector object
    public DiagramConnector ConnectorDefaults { get; set; }

    public DiagramSelectedItems SelectedItems;

    ObservableCollection<DiagramNodeAnnotation> defaultAnnotationcollection = new ObservableCollection<DiagramNodeAnnotation>();

    protected override void OnInitialized()
    {
        SelectedItems = new DiagramSelectedItems();
        SelectedItems.Constraints = (SelectorConstraints.ConnectorSourceThumb | SelectorConstraints.ConnectorTargetThumb);
        @*Hidden:Lines*@
CssClass = new Dictionary<string, string>()
        {
            { "Straight", defaultCssClass },
            { "Orthogonal", defaultCssClass },
            { "Bezier", selectedCssClass },
            { "StraightWithStroke", defaultCssClass },
            { "OrthogonalWithStroke", defaultCssClass },
            { "BezierWithStroke", defaultCssClass },
            { "StraightWithDashArray", defaultCssClass },
            { "OrthogonalWithDashArray", defaultCssClass },
            { "BezierWithDashArray", defaultCssClass },
            { "CornerRadious", defaultCssClass },
            { "SourceDecorator", defaultCssClass },
            { "SourceDecoratorWithDashArray", defaultCssClass },
        };
            @*End:Hidden*@

        this.InitDiagramDefaults();

        var port1 = CreatePort("port1", 1, .25);
        var port2 = CreatePort("port2", 1, .5);
        var port3 = CreatePort("port3", 1, .75);
        var ports1 = new ObservableCollection<DiagramPort>() { port1, port2, port3 };
        var port4 = CreatePort("port4", 0, 0.46);
        var port5 = CreatePort("port5", 0, 0.5);
        var port6 = CreatePort("port6", 0, 0.54);
        var ports6 = new ObservableCollection<DiagramPort>() { port4, port5, port6 };
        var portIn = CreatePort("portIn", 0, 0.5);
        var portOut = CreatePort("portOut", 1, 0.5);
        var ports3 = new ObservableCollection<DiagramPort>() { portIn, portOut };
        var ports4 = new ObservableCollection<DiagramPort>() { portIn, portOut };
        var ports5 = new ObservableCollection<DiagramPort>() { portIn, portOut };
        var ports2 = new ObservableCollection<DiagramPort>() { portIn, portOut };

        NodeCollection = new ObservableCollection<DiagramNode>();
        CreateNode("node1", 40, 202, "Promotion");
        CreateNode("node2", 180, 202, "Lead", ports1);
        CreateNode("node3", 340, 139, "Account", ports2);
        CreateNode("node4", 340, 202, "Information", ports3);
        CreateNode("node5", 340, 264, "Opportunity", ports4);

        DiagramNode node7 = new DiagramNode();
        node7.Id = "node7";
        node7.Width = 100;
        node7.Height = 220;
        node7.OffsetX = 510;
        node7.OffsetY = 202;
        node7.Style = new NodeShapeStyle() { Fill = "#e6e0eb", StrokeColor = "#e6e0eb", StrokeWidth = 2 };
        node7.Shape = new DiagramShape() { Type = Syncfusion.Blazor.Diagrams.Shapes.Basic, BasicShape = BasicShapes.Rectangle };
        NodeCollection.Add(node7);

        DiagramNode node8 = new DiagramNode();
        node8.Id = "node8";
        node8.OffsetX = 510;
        node8.OffsetY = 119;
        node8.Style = new NodeShapeStyle() { Fill = "#6F409F", StrokeWidth = 1 };
        node8.Shape = new DiagramShape() { Type = Syncfusion.Blazor.Diagrams.Shapes.Basic, BasicShape = BasicShapes.Rectangle };
        ObservableCollection<DiagramNodeAnnotation> node8annotationcollection = new ObservableCollection<DiagramNodeAnnotation>();
        DiagramNodeAnnotation node8annotation1 = new DiagramNodeAnnotation() { Content = "Events", Style = new AnnotationStyle() { Color = "white" } };
        node8annotationcollection.Add(node8annotation1);
        node8.Annotations = node8annotationcollection;
        NodeCollection.Add(node8);

        DiagramNode node9 = new DiagramNode();
        node9.Id = "node9";
        node9.OffsetX = 510;
        node9.OffsetY = 174;
        node9.Style = new NodeShapeStyle() { Fill = "#6F409F", StrokeWidth = 1 };
        node9.Shape = new DiagramShape() { Type = Syncfusion.Blazor.Diagrams.Shapes.Basic, BasicShape = BasicShapes.Rectangle };
        ObservableCollection<DiagramNodeAnnotation> node9annotationcollection = new ObservableCollection<DiagramNodeAnnotation>();
        DiagramNodeAnnotation node9annotation1 = new DiagramNodeAnnotation() { Content = "Emails", Style = new AnnotationStyle() { Color = "white" } };
        node9annotationcollection.Add(node9annotation1);
        node9.Annotations = node9annotationcollection;
        NodeCollection.Add(node9);

        DiagramNode node10 = new DiagramNode();
        node10.Id = "node10";
        node10.OffsetX = 510;
        node10.OffsetY = 229;
        node10.Style = new NodeShapeStyle() { Fill = "#6F409F", StrokeWidth = 1 };
        node10.Shape = new DiagramShape() { Type = Syncfusion.Blazor.Diagrams.Shapes.Basic, BasicShape = BasicShapes.Rectangle };
        ObservableCollection<DiagramNodeAnnotation> node10annotationcollection = new ObservableCollection<DiagramNodeAnnotation>();
        DiagramNodeAnnotation node10annotation1 = new DiagramNodeAnnotation() { Content = "Calls", Style = new AnnotationStyle() { Color = "white" } };
        node10annotationcollection.Add(node10annotation1);
        node10.Annotations = node10annotationcollection;
        NodeCollection.Add(node10);

        DiagramNode node11 = new DiagramNode();
        node11.Id = "node11";
        node11.OffsetX = 510;
        node11.OffsetY = 284;
        node11.Style = new NodeShapeStyle() { Fill = "#6F409F", StrokeWidth = 1 };
        node11.Shape = new DiagramShape() { Type = Syncfusion.Blazor.Diagrams.Shapes.Basic, BasicShape = BasicShapes.Rectangle };
        ObservableCollection<DiagramNodeAnnotation> node11annotationcollection = new ObservableCollection<DiagramNodeAnnotation>();
        DiagramNodeAnnotation node11annotation1 = new DiagramNodeAnnotation() { Content = "Smart contents", Style = new AnnotationStyle() { Color = "white" } };
        node11annotationcollection.Add(node11annotation1);
        node11.Annotations = node11annotationcollection;
        NodeCollection.Add(node11);

        DiagramNode node6 = new DiagramNode();
        node6.Id = "node6";
        node6.Width = 100;
        node6.Height = 220;
        node6.Children = new string[] { "node7", "node8", "node9", "node10", "node11" }; ;
        node6.Style = new NodeShapeStyle() { Fill = "#e6e0eb", StrokeColor = "#e6e0eb", StrokeWidth = 2 };
        node6.Ports = ports6;
        NodeCollection.Add(node6);

        ConnectorCollection = new ObservableCollection<DiagramConnector>();
        CreateConnector("node1", "node2", null, null);
        CreateConnector("node2", "node3", "port1", "portIn");
        CreateConnector("node2", "node4", "port2", "portIn");
        CreateConnector("node2", "node5", "port3", "portIn");
        CreateConnector("node6", "node3", "port4", "portOut");
        CreateConnector("node6", "node4", "port5", "portOut");
        CreateConnector("node6", "node5", "port6", "portOut");
    }
    private void SelectionChange(IBlazorSelectionChangeEventArgs arg)
    {

        if (arg.State == EventState.Changed)
        {
            DiagramConnector connector = null;
            if (arg.NewValue.Connectors != null && arg.NewValue.Connectors.Count > 0)
            {
                connector = Diagram.GetConnector(arg.NewValue.Connectors[0].Id);
            }
            if (connector != null)
                if (connector.Constraints == (connector.Constraints | ConnectorConstraints.Default & ~(ConnectorConstraints.ReadOnly)))
                {
                    checkboxvalue = false;
                    StateHasChanged();

                }
                else
                {
                    checkboxvalue = true;
                    StateHasChanged();
                }
            {
            @*Hidden:Lines*@
            CssClass = new Dictionary<string, string>()
            {
                { "Straight", defaultCssClass },
                { "Orthogonal", defaultCssClass },
                { "Bezier", defaultCssClass },
                { "StraightWithStroke", defaultCssClass },
                { "OrthogonalWithStroke", defaultCssClass },
                { "BezierWithStroke", defaultCssClass },
                { "StraightWithDashArray", defaultCssClass },
                { "OrthogonalWithDashArray", defaultCssClass },
                { "BezierWithDashArray", defaultCssClass },
                { "CornerRadious", defaultCssClass },
                { "SourceDecorator", defaultCssClass },
                { "SourceDecoratorWithDashArray", defaultCssClass },
            };
            @*End:Hidden*@
            if (connector != null)
            {
                if (connector.Style.StrokeDashArray != "5,5" && connector.SourceDecorator.Shape == DecoratorShapes.None)
                {
                    if (connector.Type == Segments.Straight && connector.Style.StrokeWidth == 1)
                    {
                        updateSelection("Straight");

                    }
                    else if (connector.Type == Segments.Orthogonal && connector.CornerRadius == 5)
                    {
                        updateSelection("CornerRadious");
                    }
                    else if (connector.Type == Segments.Orthogonal && connector.SourceDecorator.Shape == DecoratorShapes.Circle && connector.Style.StrokeDashArray == "5,5")
                    {
                        updateSelection("SourceDecoratorWithDashArray");
                    }
                    else if (connector.Type == Segments.Orthogonal && connector.SourceDecorator.Shape == DecoratorShapes.Circle)
                    {
                        updateSelection("SourceDecorator");
                    }
                    else if (connector.Type == Segments.Orthogonal && connector.Style.StrokeWidth == 1)
                    {
                        updateSelection("Orthogonal");
                    }
                    else if (connector.Type == Segments.Bezier && connector.Style.StrokeWidth == 1)
                    {
                        updateSelection("Bezier");
                    }
                    else if (connector.Type == Segments.Straight && connector.Style.StrokeWidth == 2)
                    {
                        updateSelection("StraightWithStroke");
                    }
                    else if (connector.Type == Segments.Orthogonal && connector.Style.StrokeWidth == 2)
                    {
                        updateSelection("OrthogonalWithStroke");
                    }
                    else if (connector.Type == Segments.Bezier && connector.Style.StrokeWidth == 2)
                    {
                        updateSelection("BezierWithStroke");
                    }
                }
                if (connector.Style.StrokeDashArray == "5,5" && connector.SourceDecorator.Shape == DecoratorShapes.None)
                {
                    if (connector.Type == Segments.Straight)
                    {
                        updateSelection("StraightWithDashArray");
                    }
                    else if (connector.Type == Segments.Orthogonal)
                    {
                        updateSelection("OrthogonalWithDashArray");
                    }
                    else if (connector.Type == Segments.Bezier)
                    {
                        updateSelection("BezierWithDashArray");
                    }
                }

                if (connector.SourceDecorator.Shape == DecoratorShapes.Circle)
                {
                    if (connector.Style.StrokeDashArray == "5,5")
                    {
                        updateSelection("SourceDecoratorWithDashArray");

                    }
                    else
                    {
                        updateSelection("SourceDecorator");
                    }
                }
            }

            }
        }
    }
    private void updateSelection(string id)
    {
        for (int i = 0; i < CssClass.Count; i++)
        {
            var value = CssClass.Values.ElementAt(i);
            var key = CssClass.Keys.ElementAt(i);
            if (CssClass.ContainsKey(id) && key == id)
            {
                value = selectedCssClass;
            }
            else
            {
                value = defaultCssClass;
            }
            CssClass.Remove(key);
            CssClass.Add(key, value);
        }


        StateHasChanged();
    }
    public void ChangeConnectorAppearance(string typeSelected)
    {
        @*Hidden:Lines*@
        CssClass = new Dictionary<string, string>()
        {
            { "Straight", defaultCssClass },
            { "Orthogonal", defaultCssClass },
            { "Bezier", defaultCssClass },
            { "StraightWithStroke", defaultCssClass },
            { "OrthogonalWithStroke", defaultCssClass },
            { "BezierWithStroke", defaultCssClass },
            { "StraightWithDashArray", defaultCssClass },
            { "OrthogonalWithDashArray", defaultCssClass },
            { "BezierWithDashArray", defaultCssClass },
            { "CornerRadious", defaultCssClass },
            { "SourceDecorator", defaultCssClass },
            { "SourceDecoratorWithDashArray", defaultCssClass },
        };
    @*End:Hidden*@
        switch (typeSelected)
        {
            case "Straight":
                ApplyStyple(Segments.Straight, 1);
                break;
            case "Orthogonal":
                ApplyStyple(Segments.Orthogonal, 1);
                break;
            case "Bezier":
                ApplyStyple(Segments.Bezier, 1);
                break;
            case "StraightWithStroke":
                ApplyStyple(Segments.Straight, 2);
                break;
            case "OrthogonalWithStroke":
                ApplyStyple(Segments.Orthogonal, 2);
                break;
            case "BezierWithStroke":
                ApplyStyple(Segments.Bezier, 2);
                break;
            case "StraightWithDashArray":
                ApplyStyple(Segments.Straight, 2, true);
                break;
            case "OrthogonalWithDashArray":
                ApplyStyple(Segments.Orthogonal, 2, true);
                break;
            case "BezierWithDashArray":
                ApplyStyple(Segments.Bezier, 2, true);
                break;
            case "CornerRadious":
                ApplyStyple(Segments.Orthogonal, 2, false, false, true);
                break;
            case "SourceDecorator":
                ApplyStyple(Segments.Straight, 2, false, true);
                break;
            case "SourceDecoratorWithDashArray":
                ApplyStyple(Segments.Straight, 2, true, true);
                break;
        }

        CssClass[selectedType] = defaultCssClass;
        selectedType = typeSelected;
        CssClass[selectedType] = selectedCssClass;
    }

    private void UpdateConnectorStyle(DiagramConnector connector, Segments type, int strokeWidth, bool isDashedLine = false, bool hasSourceDecorator = false, bool isRounded = false)
    {
        if (hasSourceDecorator)
        {
            connector.SourceDecorator = new ConnectorSourceDecorator()
            {
                Shape = DecoratorShapes.Circle,
                Style = new DecoratorShapeStyle()
                {
                    StrokeColor = "#6f409f",
                    Fill = "#6f409f",
                    StrokeWidth = strokeWidth
                }
            };
        }
        else
        {
            connector.SourceDecorator.Shape = DecoratorShapes.None;
        }

        connector.Type = type;
        connector.Style.StrokeWidth = strokeWidth;
        connector.CornerRadius = isRounded ? 5 : 0;
        connector.Style.StrokeDashArray = isDashedLine ? "5,5" : "";
        connector.TargetDecorator.Style.StrokeWidth = strokeWidth;
    }

    private void ApplyStyple(Segments type, int strokeWidth, bool isDashedLine = false, bool hasSourceDecorator = false, bool isRounded = false)
    {
        Diagram.BeginUpdate();
        if (CheckValue == "All shapes")
        {
            foreach (DiagramConnector connector in Diagram.Connectors)
            {
                this.UpdateConnectorStyle(connector, type, strokeWidth, isDashedLine, hasSourceDecorator, isRounded);

            }
        }
        if (CheckValue == "Selected Shapes" && Diagram.SelectedItems.Connectors.Count > 0)
        {
            for (var i = 0; i < Diagram.SelectedItems.Connectors.Count; i++)
            {
                this.UpdateConnectorStyle(Diagram.GetConnector(Diagram.SelectedItems.Connectors[i].Id), type, strokeWidth, isDashedLine, hasSourceDecorator, isRounded);
            }
        };

        Diagram.EndUpdate();

    }



    private void UpdateConstraintsValue(DiagramConnector connector, Syncfusion.Blazor.Buttons.ChangeEventArgs<bool> args)
    {

        if (args.Checked)
        {
            connector.Constraints = (connector.Constraints & ~(ConnectorConstraints.DragSourceEnd
                | ConnectorConstraints.DragTargetEnd | ConnectorConstraints.DragSegmentThumb)) | ConnectorConstraints.ReadOnly;
        }
        else
        {
            connector.Constraints |= ConnectorConstraints.Default & ~(ConnectorConstraints.ReadOnly);
        }
    }

    public void ConstraintsChange(Syncfusion.Blazor.Buttons.ChangeEventArgs<bool> args)
    {
        checkboxvalue = args.Checked;
        Diagram.BeginUpdate();
        if (Diagram.Connectors.Count > 0)
        {
            if (CheckValue == "All shapes")
            {
                for (int i = 0; i < Diagram.Connectors.Count; i++)
                {
                    this.UpdateConstraintsValue(Diagram.Connectors[i], args);
                }
            }
            if (CheckValue == "Selected Shapes" && Diagram.SelectedItems.Connectors.Count > 0)
            {
                for (var i = 0; i < Diagram.SelectedItems.Connectors.Count; i++)
                {
                    this.UpdateConstraintsValue(Diagram.GetConnector(Diagram.SelectedItems.Connectors[i].Id), args);
                }
            };
            Diagram.EndUpdate();

        }

    }

    private void InitDiagramDefaults()
    {
        DiagramNodeAnnotation defaultAnnotation = new DiagramNodeAnnotation()
        {
            Style = new AnnotationStyle()
            {
                Color = "white",
                Fill = "transparent"
            }
        };



        NodeDefaults = new DiagramNode()
        {
            Width = 80,
            Height = 35,
            Style = new NodeShapeStyle() { StrokeColor = "#6F409F", StrokeWidth = 2 }
        };

        ConnectorDefaults = new DiagramConnector()
        {
            TargetDecorator = new ConnectorTargetDecorator()
            {
                Shape = DecoratorShapes.Arrow,
                Style = new DecoratorShapeStyle() { Fill = "#6f409f", StrokeColor = "#6f409f", StrokeWidth = 2 }
            },
            Style = new ConnectorShapeStyle() { StrokeColor = "#6f409f", StrokeWidth = 2 },
            Type = Segments.Bezier,
        };
    }

    private DiagramPort CreatePort(string id, double x, double y)
    {
        return new DiagramPort()
        {
            Id = id,
            Offset = new NodePortOffset() { X = x, Y = y },
            Visibility = PortVisibility.Hidden
        };
    }

    private void CreateNode(string id, double x, double y, string label, object ports = null)
    {
        DiagramNodeAnnotation annotation = new DiagramNodeAnnotation() { Content = label };
        DiagramNode diagramNode = new DiagramNode()
        {
            Id = id,
            OffsetX = x,
            OffsetY = y,
            Shape = new DiagramShape() { Type = DiagramShapes.Basic, BasicShape = BasicShapes.Rectangle, CornerRadius = 10 },
            Annotations = new ObservableCollection<DiagramNodeAnnotation>() { annotation }
        };

        if (ports != null)
        {
            diagramNode.Ports = ports as ObservableCollection<DiagramPort>;
        }

        NodeCollection.Add(diagramNode);
    }

    private void CreateConnector(string sourceId, string targetId, string sourcePort, string targetPort)
    {
        DiagramConnector diagramConnector = new DiagramConnector()
        {
            Id = string.Format("connector{0}", ++connectorCount),
            SourceID = sourceId,
            TargetID = targetId,
            SourcePortID = sourcePort,
            TargetPortID = targetPort,
            Type = Segments.Bezier

        };

        ConnectorCollection.Add(diagramConnector);
    }
    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        if (firstRender)
        {
            await Task.Delay(500);
            StateHasChanged();
        }
    }
}
